/**
 * @file thread9.c
 * @brief RS485多设备通信线程实现
 * 
 * 该线程负责通过RS485接口与多个设备通信。主要功能包括：
 * 1. 初始化RS485串口接口（/dev/ttyS5）
 * 2. 轮询访问多个设备（风速仪、温湿度传感器、4个拉力传感器）
 * 3. 解析不同设备的响应数据
 * 4. 将解析后的数据存储在全局结构体中
 * 5. 提供接口供其他线程获取设备数据
 * 
 * @author 伞控无人机项目组
 * @date 2023
 */

/**
 * @brief 线程9设备通信协议说明
 * 
 * 1. 风速仪通信协议 (Modbus RTU格式)：
 *    - 设备地址: 0x02
 *    - 功能码: 0x03 (读保持寄存器)
 *    - 寄存器地址: 0x0000 (起始地址)
 *    - 寄存器数量: 41 (0x29)
 *    - 数据格式: 
 *      风向值 = 寄存器0 (16位整数，0~369度)
 *      风速值 = 寄存器1-2 (32位IEEE-754浮点数)
 *    - 请求帧: 0x02 0x03 0x00 0x00 0x00 0x29 CRC_L CRC_H
 *    - 响应帧: 0x02 0x03 0x52 风向高字节 风向低字节 风速字节1 风速字节2 风速字节3 风速字节4 ... CRC_L CRC_H
 *    - 示例: 02 03 52 00 02 01 51 A8 9B 40 6B ... 79 53
 *      风向: 0x0151 = 337度
 *      风速: A8 9B 40 6B -> 0x406ba89b = 3.6821658611297607 m/s
 * 
 * 2. 温湿度传感器通信协议 (Modbus RTU格式)：
 *    - 设备地址: 0x01
 *    - 功能码: 0x04 (读输入寄存器)
 *    - 寄存器地址: 0x0000 (温度), 0x0001 (湿度)
 *    - 寄存器数量: 2
 *    - 数据格式: 
 *      温度值 = 寄存器值 * 0.1 (摄氏度)
 *      湿度值 = 寄存器值 * 0.1 (%RH)
 *    - 请求帧: 0x01 0x04 0x00 0x00 0x00 0x02 CRC_L CRC_H
 *    - 响应帧: 0x01 0x04 0x04 温度高字节 温度低字节 湿度高字节 湿度低字节 CRC_L CRC_H
 *    - 数据范围: 温度 -40~125℃, 湿度 0~100%RH
 * 
 * 3. 拉力传感器通信协议 (Modbus RTU格式, 7系放大器通讯协议V3.1)：
 *    - 设备地址: 0x03~0x06 (4个拉力传感器)
 *    - 功能码: 0x03 (读保持寄存器)
 *    - 寄存器地址: 0x0001
 *    - 寄存器数量: 2 (32位浮点数需要两个寄存器)
 *    - 数据格式: IEEE-754浮点数格式
 *      拉力值直接从32位浮点数中解析，无需缩放因子
 *    - 请求帧: 设备地址 0x03 0x00 0x01 0x00 0x02 CRC_L CRC_H
 *    - 响应帧: 设备地址 0x03 0x04 byte1 byte2 byte3 byte4 CRC_L CRC_H
 *      (byte1~byte4为IEEE-754格式的32位浮点数，高字节在前)
 *    - 错误帧: 设备地址 (0x80|功能码) 错误码 CRC_L CRC_H
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <pthread.h>
#include <stdint.h>
#include <time.h>
#include <ctype.h>
#include "thread9.h"
#include "log_utils.h"
#include <math.h> // 添加头文件，消除 isnan/isinf 警告
#include <sys/ioctl.h>  // 添加ioctl头文件，支持串口控制
#include <linux/serial.h> // 添加串口结构体头文件
#include "uart_common.h"

// 模块名称定义
#define RS485_MODULE LOG_MODULE_RS485

// 全局变量定义
anemometer_data_t g_anemometer_data = {0};            // 风速仪数据
temp_humid_data_t g_temp_humid_data = {0};            // 温湿度传感器数据
force_sensor_data_t g_force_sensor_data[4] = {0};     // 4个拉力传感器数据
pthread_mutex_t g_rs485_data_mutex = PTHREAD_MUTEX_INITIALIZER;  // 数据互斥锁

// 内部变量
static int g_rs485_fd = -1;                           // 串口文件描述符
static int g_thread_running = 1;                      // 线程运行标志

// 内部函数声明
static int build_modbus_request(uint8_t device_addr, uint8_t function_code, 
                               uint16_t start_addr, uint16_t reg_count, 
                               uint8_t *buffer);
static int parse_anemometer_data(uint8_t *buffer, int length);
static int parse_temp_humid_data(uint8_t *buffer, int length);
static int parse_force_sensor_data(uint8_t *buffer, int length, int sensor_idx);

/**
 * @brief 初始化RS485串口（公共接口）
 * 
 * @param device 设备路径
 * @param baudrate 波特率
 * @return int 成功返回文件描述符，失败返回-1
 */
int rs485_init(const char *device, int baudrate) {
    // 使用新的UART通用模块初始化串口
    uart_config_t config = {
        .baudrate = baudrate,
        .data_bits = 8,
        .stop_bits = 1,
        .parity = 0,
        .flow_control = 0,
        .timeout_ms = 200,   // RS485需要更长的超时时间
        .buffer_size = 65536,
        .flags = UART_FLAG_RAW_MODE | UART_FLAG_LARGE_BUFFER
    };
    
    int fd = uart_init_device(device, UART_TYPE_RS485, &config);
    if (fd < 0) {
        LOG_ERROR(LOG_TO_FILE, RS485_MODULE, "打开设备%s失败: %s", device, strerror(errno));
        return -1;
    }
    
    // 清空缓冲区
    uart_flush_buffer(fd, TCIOFLUSH);
    
    LOG_INFO(LOG_TO_FILE, RS485_MODULE, "RS485串口 %s 初始化成功，波特率: %d", device, baudrate);
    return fd;
}

/**
 * @brief 发送Modbus请求并等待响应
 * 
 * @param fd 串口文件描述符
 * @param tx_buffer 发送缓冲区
 * @param tx_len 发送数据长度
 * @param rx_buffer 接收缓冲区
 * @param rx_buffer_size 接收缓冲区大小
 * @param timeout_ms 超时时间（毫秒）
 * @return 接收到的数据长度，超时或错误返回负数
 */
int rs485_send_receive(int fd, const uint8_t *tx_buffer, int tx_len, 
                      uint8_t *rx_buffer, int rx_buffer_size, int timeout_ms) {
    int ret;
    fd_set readfds;
    struct timeval timeout;
    int total_received = 0;
    int bytes_received = 0;
    time_t start_time = time(NULL);
    time_t current_time;
    
    // 参数检查
    if (fd < 0) {
        LOG_ERROR(LOG_TO_FILE, RS485_MODULE, "无效的文件描述符");
        return -1;
    }
    
    // 如果有数据要发送
    if (tx_buffer != NULL && tx_len > 0) {
        // 清空接收缓冲区
        tcflush(fd, TCIFLUSH);
        
        // 打印发送的原始数据
        char hex_debug[512] = {0};
        for (int i = 0; i < tx_len && i < 80; i++) {  // 最多显示80字节
            sprintf(hex_debug + i * 3, "%02X ", tx_buffer[i]);
        }
        LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "发送请求帧(%d字节): %s", tx_len, hex_debug);
        
        // 发送数据
        ret = write(fd, tx_buffer, tx_len);
        if (ret != tx_len) {
            LOG_ERROR(LOG_TO_FILE, RS485_MODULE, "发送数据失败: %s", strerror(errno));
            return -1;
        }
        
        // 等待发送完成
        tcdrain(fd);
    }
    
    // 如果不需要接收数据
    if (rx_buffer == NULL || rx_buffer_size <= 0) {
        return 0;
    }
    
    // 等待100ms，让对方设备有时间处理和响应
    usleep(100000);

    // 多次接收循环，直到接收完整或超时
    start_time = time(NULL);
    while (total_received < rx_buffer_size) {
        current_time = time(NULL);
        
        // 检查总超时时间
        if ((current_time - start_time) * 1000 >= timeout_ms) {
            LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "接收超时，已接收%d字节", total_received);
            break;
        }
        
        // 设置select超时（剩余时间或100ms，取较小值）
        int remaining_ms = timeout_ms - (current_time - start_time) * 1000;
        int select_timeout_ms = (remaining_ms < 100) ? remaining_ms : 100;
        
        timeout.tv_sec = select_timeout_ms / 1000;
        timeout.tv_usec = (select_timeout_ms % 1000) * 1000;
        
        // 等待数据可读
        FD_ZERO(&readfds);
        FD_SET(fd, &readfds);
        
        ret = select(fd + 1, &readfds, NULL, NULL, &timeout);
        if (ret < 0) {
            LOG_ERROR(LOG_TO_FILE, RS485_MODULE, "select失败: %s", strerror(errno));
            return -1;
        } else if (ret == 0) {
            // 这次select超时，但可能还有数据在路上
            if (total_received > 0) {
                // 如果已经接收到一些数据，再等待一小段时间看是否有更多数据
                usleep(30000);  // 等待30ms，适应9600波特率
                continue;
            } else {
                // 完全没有数据，真正超时
                LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "接收超时，无数据");
                return 0;
            }
        }
        
        // 读取数据
        bytes_received = read(fd, rx_buffer + total_received, rx_buffer_size - total_received);
        if (bytes_received < 0) {
            LOG_ERROR(LOG_TO_FILE, RS485_MODULE, "读取数据失败: %s", strerror(errno));
            return -1;
        } else if (bytes_received == 0) {
            // 没有更多数据
            break;
        }
        
        total_received += bytes_received;
        LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "本次接收%d字节，累计%d字节", bytes_received, total_received);
        
        // 对于Modbus协议，检查是否已接收完整帧
        if (total_received >= 3) {
            // 检查是否是Modbus响应
            if (rx_buffer[1] == 0x03 || rx_buffer[1] == 0x04) {
                // 计算期望的总长度：地址(1) + 功能码(1) + 数据长度(1) + 数据(N) + CRC(2)
                int expected_length = 3 + rx_buffer[2] + 2;
                if (total_received >= expected_length) {
                    LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "Modbus帧接收完整：%d/%d字节", total_received, expected_length);
                    break;
                }
            }
        }
        
        // 如果连续没有新数据，可能接收完成
        if (bytes_received == 0) {
            usleep(20000);  // 等待20ms看是否还有数据，适应9600波特率
        }
    }
    
    LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "接收完成，总共%d字节", total_received);
    return total_received;
}

/**
 * @brief 计算Modbus CRC16校验码
 * 
 * @param buffer 数据缓冲区
 * @param length 数据长度
 * @return CRC16校验码
 */
uint16_t modbus_crc16(const uint8_t *buffer, int length) {
    uint16_t crc = 0xFFFF;
    int i, j;
    
    for (i = 0; i < length; i++) {
        crc ^= (uint16_t)buffer[i];
        
        for (j = 0; j < 8; j++) {
            if ((crc & 0x0001) != 0) {
                crc >>= 1;
                crc ^= 0xA001;
            } else {
                crc >>= 1;
            }
        }
    }
    
    return crc;
}

/**
 * @brief 构建Modbus请求
 * 
 * @param device_addr 设备地址
 * @param function_code 功能码
 * @param start_addr 起始地址
 * @param reg_count 寄存器数量
 * @param buffer 输出缓冲区
 * @return 请求长度
 */
static int build_modbus_request(uint8_t device_addr, uint8_t function_code, 
                               uint16_t start_addr, uint16_t reg_count, 
                               uint8_t *buffer) {
    uint16_t crc;
    
    // 设备地址
    buffer[0] = device_addr;
    
    // 功能码
    buffer[1] = function_code;
    
    // 起始地址（高字节在前）
    buffer[2] = (start_addr >> 8) & 0xFF;
    buffer[3] = start_addr & 0xFF;
    
    // 寄存器数量（高字节在前）
    buffer[4] = (reg_count >> 8) & 0xFF;
    buffer[5] = reg_count & 0xFF;
    
    // 计算CRC校验码
    crc = modbus_crc16(buffer, 6);
    
    // 添加CRC校验码（低字节在前）
    buffer[6] = crc & 0xFF;
    buffer[7] = (crc >> 8) & 0xFF;
    
    return 8;  // 请求长度为8字节
}

/**
 * @brief 解析风速仪数据（Modbus RTU格式）
 * 
 * @param buffer 接收到的数据缓冲区
 * @param length 数据长度
 * @return 0-成功，-1-失败
 */
static int parse_anemometer_data(uint8_t *buffer, int length) {
    // 检查参数
    if (buffer == NULL || length < 9) {
        LOG_WARN(LOG_TO_FILE, RS485_MODULE, "风速仪数据长度不足: %d字节 (需要至少9字节)", length);
        return -1;
    }
    
    // 检查Modbus响应格式
    if (buffer[0] != ANEMOMETER_ADDR || buffer[1] != MODBUS_READ_HOLDING_REGISTERS) {
        LOG_WARN(LOG_TO_FILE, RS485_MODULE, "风速仪响应格式错误: 地址=0x%02X(期望0x%02X), 功能码=0x%02X(期望0x%02X)", 
                 buffer[0], ANEMOMETER_ADDR, buffer[1], MODBUS_READ_HOLDING_REGISTERS);
        return -1;
    }
    
    // 检查数据长度字段
    uint8_t data_len = buffer[2];
    if (data_len < 6) {  // 至少需要风向(2字节) + 风速(4字节)
        LOG_WARN(LOG_TO_FILE, RS485_MODULE, "风速仪数据长度字段错误: %d字节 (期望至少6字节)", data_len);
        return -1;
    }
    
    // 检查总长度
    int expected_length = 3 + data_len + 2;  // 地址(1) + 功能码(1) + 长度(1) + 数据(data_len) + CRC(2)
    if (length < expected_length) {
        LOG_WARN(LOG_TO_FILE, RS485_MODULE, "风速仪响应长度不足: %d字节 (期望%d字节)", length, expected_length);
        return -1;
    }
    
    // 计算CRC校验
    uint16_t crc = modbus_crc16(buffer, length - 2);
    // Modbus RTU的CRC是低字节在前，高字节在后
    uint16_t recv_crc = buffer[length - 2] | (buffer[length - 1] << 8);
    
    LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "风速仪CRC校验: 计算值=0x%04X, 接收值=0x%04X (字节: %02X %02X)", 
              crc, recv_crc, buffer[length - 2], buffer[length - 1]);
    
    if (crc != recv_crc) {
        LOG_WARN(LOG_TO_FILE, RS485_MODULE, "风速仪CRC校验错误: 计算=0x%04X, 接收=0x%04X", crc, recv_crc);
        return -1;
    }
    
    // 解析风向数据 (寄存器0，2字节，16位整数)
    // 根据实际数据：01 5E 在 buffer[5] 和 buffer[6]
    uint16_t wind_direction_raw = (buffer[5] << 8) | buffer[6];
    float wind_direction = (float)wind_direction_raw;  // 直接转换，0~369度
    
    LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "风向原始数据: 0x%04X = %d度", wind_direction_raw, (int)wind_direction);
    
    // 解析风速数据 (寄存器1-2，4字节，IEEE-754浮点数)
    // 根据实际数据：E9 79 40 2F -> 0x402F79E9
    // 字节顺序：buffer[5]=E9, buffer[6]=79, buffer[7]=40, buffer[8]=2F
    union {
        float f;
        uint32_t i;
    } wind_speed_union;
    
    // 正确的字节顺序重排：43 96 40 18 -> 40 18 43 96
    wind_speed_union.i = ((uint32_t)buffer[9] << 24) |  // 40 -> 最高字节
                         ((uint32_t)buffer[10] << 16) |  // 18 -> 次高字节  
                         ((uint32_t)buffer[7] << 8) |   // 43 -> 次低字节
                         buffer[8];                     // 96 -> 最低字节
    
    float wind_speed = wind_speed_union.f;
    
    LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "风速原始数据: %02X %02X %02X %02X -> 0x%08X -> %.6f m/s", 
              buffer[7], buffer[8], buffer[9], buffer[10], wind_speed_union.i, wind_speed);
    
    // 检查数据合理性
    if (wind_direction < 0.0f || wind_direction > 360.0f) {
        LOG_WARN(LOG_TO_FILE, RS485_MODULE, "风向数据异常: %.1f度", wind_direction);
        return -1;
    }
    
    if (isnan(wind_speed) || isinf(wind_speed) || wind_speed < 0.0f || wind_speed > 100.0f) {
        LOG_WARN(LOG_TO_FILE, RS485_MODULE, "风速数据异常: %.6f m/s", wind_speed);
         return -1;
    }
    
    // 更新全局数据
    pthread_mutex_lock(&g_rs485_data_mutex);
    g_anemometer_data.wind_speed = wind_speed;
    g_anemometer_data.wind_direction = wind_direction;
    g_anemometer_data.timestamp = time(NULL);
    g_anemometer_data.data_valid = 1;
    pthread_mutex_unlock(&g_rs485_data_mutex);
    
    // 使用标准化数据记录格式
    LOG_DATA_RECORD(LOG_MODULE_WIND, LOG_DATA_WIND_SPD, "speed=%.6f", wind_speed);
    LOG_DATA_RECORD(LOG_MODULE_WIND, LOG_DATA_WIND_DIR, "direction=%.1f", wind_direction);
    
    return 0;
}

/**
 * @brief 解析温湿度传感器数据（Modbus格式）
 * 
 * @param buffer 接收到的数据缓冲区
 * @param length 数据长度
 * @return 0-成功，-1-失败
 */
static int parse_temp_humid_data(uint8_t *buffer, int length) {
    // 检查参数
    if (buffer == NULL || length < 9) {
        LOG_WARN(LOG_TO_FILE, RS485_MODULE, "温湿度数据长度不足: %d字节 (需要至少9字节)", length);
        return -1;
    }
    
    // 检查Modbus响应格式
    if (buffer[0] != TEMP_HUMID_ADDR || buffer[1] != MODBUS_READ_INPUT_REGISTERS) {
        LOG_WARN(LOG_TO_FILE, RS485_MODULE, "温湿度响应格式错误: 地址=0x%02X(期望0x%02X), 功能码=0x%02X(期望0x%02X)", 
                 buffer[0], TEMP_HUMID_ADDR, buffer[1], MODBUS_READ_INPUT_REGISTERS);
        return -1;
    }
    
    // 检查数据长度
    if (buffer[2] != 4) {  // 4字节数据
        LOG_WARN(LOG_TO_FILE, RS485_MODULE, "温湿度数据长度字段错误: %d字节 (期望4字节)", buffer[2]);
        return -1;
    }
    
    // 计算CRC校验
    uint16_t crc = modbus_crc16(buffer, length - 2);
    // Modbus RTU的CRC是低字节在前，高字节在后
    uint16_t recv_crc = buffer[length - 2] | (buffer[length - 1] << 8);
    
    LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "温湿度CRC校验: 计算值=0x%04X, 接收值=0x%04X (字节: %02X %02X)", 
              crc, recv_crc, buffer[length - 2], buffer[length - 1]);
    
    if (crc != recv_crc) {
        LOG_WARN(LOG_TO_FILE, RS485_MODULE, "温湿度传感器CRC校验错误: 计算=0x%04X, 接收=0x%04X", crc, recv_crc);
        return -1;
    }
    
    // 解析温度和湿度数据
    int16_t temp_raw = (buffer[3] << 8) | buffer[4];
    int16_t humid_raw = (buffer[5] << 8) | buffer[6];
    
    LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "温湿度原始数据: 温度=%d, 湿度=%d", temp_raw, humid_raw);
    
    // 转换为实际值
    float temperature = temp_raw * 0.1f;
    float humidity = humid_raw * 0.1f;
    
    LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "温湿度转换后: 温度=%.1f°C, 湿度=%.1f%%", temperature, humidity);
    
    // 检查数据合理性
    if (temperature < -40.0f || temperature > 125.0f) {
        LOG_WARN(LOG_TO_FILE, RS485_MODULE, "温度数据异常: %.1f°C", temperature);
        return -1;
    }
    
    if (humidity < 0.0f || humidity > 100.0f) {
        LOG_WARN(LOG_TO_FILE, RS485_MODULE, "湿度数据异常: %.1f%%", humidity);
        return -1;
    }
    
    // 更新全局数据
    pthread_mutex_lock(&g_rs485_data_mutex);
    g_temp_humid_data.temperature = temperature;
    g_temp_humid_data.humidity = humidity;
    g_temp_humid_data.timestamp = time(NULL);
    g_temp_humid_data.data_valid = 1;
    pthread_mutex_unlock(&g_rs485_data_mutex);
    
    // 使用标准化数据记录格式
    LOG_DATA_RECORD(LOG_MODULE_TEMP, LOG_DATA_TEMP_VAL, "temperature=%.1f", temperature);
    LOG_DATA_RECORD(LOG_MODULE_TEMP, LOG_DATA_HUMID_VAL, "humidity=%.1f", humidity);
    
    return 0;
}

/**
 * @brief 解析拉力传感器数据（Modbus格式）
 * 
 * @param buffer 接收到的数据缓冲区
 * @param length 数据长度
 * @param sensor_idx 传感器索引（0-3）
 * @return 0-成功，-1-失败
 */
__attribute__((unused))
static int parse_force_sensor_data(uint8_t *buffer, int length, int sensor_idx) {
    // 检查参数
    if (buffer == NULL || length < 9 || sensor_idx < 0 || sensor_idx >= 4) {
        return -1;
    }
    
    uint8_t device_addr = FORCE_SENSOR1_ADDR + sensor_idx;
    
    // 检查Modbus响应格式
    if (buffer[0] != device_addr || buffer[1] != MODBUS_READ_HOLDING_REGISTERS) {
        return -1;
    }
    
    // 检查数据长度
    if (buffer[2] != 4) {  // 4字节数据
        return -1;
    }
    
    // 计算CRC校验
    uint16_t crc = modbus_crc16(buffer, length - 2);
    uint16_t recv_crc = (buffer[length - 1] << 8) | buffer[length - 2];
    
    if (crc != recv_crc) {
        LOG_WARN(LOG_TO_FILE, RS485_MODULE, "拉力传感器%d CRC校验错误", sensor_idx + 1);
        return -1;
    }
    
    // 解析IEEE-754浮点数
    // 注意：这里假设接收到的字节顺序是高字节在前（大端序）
    // 如果实际设备使用小端序，需要调整字节顺序
    union {
        float f;
        uint32_t i;
    } value;
    
    value.i = ((uint32_t)buffer[3] << 24) | 
              ((uint32_t)buffer[4] << 16) | 
              ((uint32_t)buffer[5] << 8) | 
              buffer[6];
    
    float force = value.f;
    
    // 检查数据合理性
    if (isnan(force) || isinf(force) || force < -10000.0f || force > 10000.0f) {
        LOG_WARN(LOG_TO_FILE, RS485_MODULE, "拉力传感器%d数据异常: %f", sensor_idx + 1, force);
        return -1;
    }
    
    // 更新全局数据
    pthread_mutex_lock(&g_rs485_data_mutex);
    g_force_sensor_data[sensor_idx].force = force;
    g_force_sensor_data[sensor_idx].timestamp = time(NULL);
    g_force_sensor_data[sensor_idx].data_valid = 1;
    pthread_mutex_unlock(&g_rs485_data_mutex);
    
    // 使用标准化数据记录格式
    LOG_DATA_RECORD(LOG_MODULE_FORCE, LOG_DATA_FORCE_VAL, "sensor_id=%d,force=%.2f", sensor_idx + 1, force);
    
    return 0;
} 

/**
 * @brief 获取风速仪数据
 * 
 * @param data 数据结构体指针
 * @return 0-成功，-1-失败
 */
int get_anemometer_data(anemometer_data_t *data) {
    if (data == NULL) {
        return -1;
    }
    
    pthread_mutex_lock(&g_rs485_data_mutex);
    *data = g_anemometer_data;
    pthread_mutex_unlock(&g_rs485_data_mutex);
    
    return 0;
}

/**
 * @brief 获取温湿度传感器数据
 * 
 * @param data 数据结构体指针
 * @return 0-成功，-1-失败
 */
int get_temp_humid_data(temp_humid_data_t *data) {
    if (data == NULL) {
        return -1;
    }
    
    pthread_mutex_lock(&g_rs485_data_mutex);
    *data = g_temp_humid_data;
    pthread_mutex_unlock(&g_rs485_data_mutex);
    
    return 0;
}

/**
 * @brief 获取拉力传感器数据
 * 
 * @param sensor_idx 传感器索引（0-3）
 * @param data 数据结构体指针
 * @return 0-成功，-1-失败
 */
int get_force_sensor_data(int sensor_idx, force_sensor_data_t *data) {
    if (data == NULL || sensor_idx < 0 || sensor_idx > 3) {
        return -1;
    }
    
    pthread_mutex_lock(&g_rs485_data_mutex);
    *data = g_force_sensor_data[sensor_idx];
    pthread_mutex_unlock(&g_rs485_data_mutex);
    
    return 0;
}

/**
 * @brief 关闭RS485串口
 * 
 * @param fd 串口文件描述符
 */
void rs485_close(int fd) {
    if (fd >= 0) {
        close(fd);
        LOG_INFO(LOG_TO_FILE, RS485_MODULE, "串口已关闭");
    }
}

/**
 * @brief 线程9主函数 - RS485多设备通信
 * 
 * @param arg 线程参数
 * @return void* 
 */
void *thread9_function(void *arg) {
    (void)arg;
    uint8_t tx_buffer[RS485_TX_BUFFER_SIZE];  // 发送缓冲区
    uint8_t rx_buffer[RS485_RX_BUFFER_SIZE];  // 接收缓冲区
    int tx_len, rx_len;
    int i;
    int consecutive_failures = 0;
    struct timespec poll_interval = {0, 500000000};  // 初始为100ms
    time_t last_success_time = 0;
    time_t current_time;
    time_t last_status_report_time = 0;
    char tx_hex_string[RS485_TX_BUFFER_SIZE * 3 + 1];  // 发送帧十六进制字符串
    char rx_hex_string[RS485_RX_BUFFER_SIZE * 3 + 1];  // 接收帧十六进制字符串
    char hex_string[RS485_RX_BUFFER_SIZE * 3 + 1];     // 调试用十六进制字符串
    
    LOG_INFO(LOG_TO_FILE, RS485_MODULE, "线程9启动: 多设备通信");
    
    // 初始化RS485串口
    g_rs485_fd = rs485_init(RS485_DEVICE, RS485_BAUDRATE);
    if (g_rs485_fd < 0) {
        LOG_ERROR(LOG_TO_FILE, RS485_MODULE, "初始化串口失败，线程9退出");
        return NULL;
    }
    
    // 初始化所有设备数据为无效
    pthread_mutex_lock(&g_rs485_data_mutex);
    g_anemometer_data.data_valid = 0;
    g_temp_humid_data.data_valid = 0;
    for (i = 0; i < 4; i++) {
        g_force_sensor_data[i].data_valid = 0;
    }
    pthread_mutex_unlock(&g_rs485_data_mutex);
    
    // 主循环
    while (g_thread_running) {
        current_time = time(NULL);
        
        // 定期报告传感器状态（每60秒一次）
        if (current_time - last_status_report_time > 60) {
            LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "传感器状态: 风速仪[%s], 温湿度[%s], 拉力1-4[%s,%s,%s,%s]",
                      g_anemometer_data.data_valid ? "在线" : "离线",
                      g_temp_humid_data.data_valid ? "在线" : "离线",
                      g_force_sensor_data[0].data_valid ? "在线" : "离线",
                      g_force_sensor_data[1].data_valid ? "在线" : "离线",
                      g_force_sensor_data[2].data_valid ? "在线" : "离线",
                      g_force_sensor_data[3].data_valid ? "在线" : "离线");
            last_status_report_time = current_time;
        }
        
        // 如果长时间没有成功通信，尝试重新初始化串口
        if (last_success_time > 0 && current_time - last_success_time > RS485_REINIT_TIMEOUT_SEC) {
            LOG_WARN(LOG_TO_FILE, RS485_MODULE, "通信长时间失败，尝试重新初始化串口");
            rs485_close(g_rs485_fd);
            usleep(500000);  // 等待500ms
            g_rs485_fd = rs485_init(RS485_DEVICE, RS485_BAUDRATE);
            if (g_rs485_fd < 0) {
                LOG_ERROR(LOG_TO_FILE, RS485_MODULE, "重新初始化串口失败，等待10秒后重试");
                sleep(10);
                continue;
            }
            last_success_time = current_time;
        }
        
        // 1. 查询风速仪数据（Modbus RTU格式）
        memset(tx_buffer, 0, RS485_TX_BUFFER_SIZE);
        tx_len = build_modbus_request(ANEMOMETER_ADDR, MODBUS_READ_HOLDING_REGISTERS, 0, 41, tx_buffer); // 读取41个寄存器(0x29)
        
        // 记录风速仪请求帧到日志文件（INFO级别）
        memset(tx_hex_string, 0, sizeof(tx_hex_string));
        for (int j = 0; j < tx_len; j++) {
            sprintf(tx_hex_string + j * 3, "%02X ", tx_buffer[j]);
        }
        if (strlen(tx_hex_string) > 0) {
            tx_hex_string[strlen(tx_hex_string) - 1] = '\0';
        }
        LOG_INFO(LOG_TO_FILE, RS485_MODULE, "风速仪请求帧(%d字节): %s", tx_len, tx_hex_string);
        
        memset(rx_buffer, 0, RS485_RX_BUFFER_SIZE);
        rx_len = rs485_send_receive(g_rs485_fd, tx_buffer, tx_len, rx_buffer, RS485_RX_BUFFER_SIZE, RS485_RESPONSE_TIMEOUT_MS);
        
        if (rx_len > 0) {
            // 记录风速仪响应帧到日志文件（INFO级别）
            memset(rx_hex_string, 0, sizeof(rx_hex_string));
            for (int j = 0; j < rx_len; j++) {
                sprintf(rx_hex_string + j * 3, "%02X ", rx_buffer[j]);
            }
            if (strlen(rx_hex_string) > 0) {
                rx_hex_string[strlen(rx_hex_string) - 1] = '\0';
            }
            LOG_INFO(LOG_TO_FILE, RS485_MODULE, "风速仪响应帧(%d字节): %s", rx_len, rx_hex_string);
            
            // 添加接收帧的调试信息 - 格式化为完整的十六进制字符串
            memset(hex_string, 0, sizeof(hex_string));
            for (int j = 0; j < rx_len; j++) {
                sprintf(hex_string + j * 3, "%02X ", rx_buffer[j]);
            }
            // 移除最后一个空格
            if (strlen(hex_string) > 0) {
                hex_string[strlen(hex_string) - 1] = '\0';
            }
            LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "接收到风速仪响应帧(%d字节): %s", rx_len, hex_string);
            
            // 尝试解析风速仪数据
            if (parse_anemometer_data(rx_buffer, rx_len) == 0) {
                LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "风速仪: %.1f m/s, %.1f°", 
                          g_anemometer_data.wind_speed, g_anemometer_data.wind_direction);
                last_success_time = current_time;
                consecutive_failures = 0;
            } else {
                LOG_WARN(LOG_TO_FILE, RS485_MODULE, "风速仪数据解析失败");
                consecutive_failures++;
            }
        } else {
            LOG_WARN(LOG_TO_FILE, RS485_MODULE, "风速仪传感器无响应或超时");
            consecutive_failures++;
        }
        
        // 短暂延时，避免总线冲突
        nanosleep(&poll_interval, NULL);
       
        // 2. 查询温湿度传感器数据（Modbus RTU格式）
        memset(tx_buffer, 0, RS485_TX_BUFFER_SIZE);
        tx_len = build_modbus_request(TEMP_HUMID_ADDR, MODBUS_READ_INPUT_REGISTERS, 0, 2, tx_buffer);
        
        // 记录温湿度传感器请求帧到日志文件（INFO级别）
        memset(tx_hex_string, 0, sizeof(tx_hex_string));
        for (int j = 0; j < tx_len; j++) {
            sprintf(tx_hex_string + j * 3, "%02X ", tx_buffer[j]);
        }
        if (strlen(tx_hex_string) > 0) {
            tx_hex_string[strlen(tx_hex_string) - 1] = '\0';
        }
        LOG_INFO(LOG_TO_FILE, RS485_MODULE, "温湿度传感器请求帧(%d字节): %s", tx_len, tx_hex_string);
        
        memset(rx_buffer, 0, RS485_RX_BUFFER_SIZE);
        rx_len = rs485_send_receive(g_rs485_fd, tx_buffer, tx_len, rx_buffer, RS485_RX_BUFFER_SIZE, RS485_RESPONSE_TIMEOUT_MS);
        
        if (rx_len > 0) {
            // 记录温湿度传感器响应帧到日志文件（INFO级别）
            memset(rx_hex_string, 0, sizeof(rx_hex_string));
            for (int j = 0; j < rx_len; j++) {
                sprintf(rx_hex_string + j * 3, "%02X ", rx_buffer[j]);
            }
            if (strlen(rx_hex_string) > 0) {
                rx_hex_string[strlen(rx_hex_string) - 1] = '\0';
            }
            LOG_INFO(LOG_TO_FILE, RS485_MODULE, "温湿度传感器响应帧(%d字节): %s", rx_len, rx_hex_string);
            
            // 添加接收帧的调试信息 - 格式化为完整的十六进制字符串
            memset(hex_string, 0, sizeof(hex_string));
            for (int j = 0; j < rx_len; j++) {
                sprintf(hex_string + j * 3, "%02X ", rx_buffer[j]);
            }
            // 移除最后一个空格
            if (strlen(hex_string) > 0) {
                hex_string[strlen(hex_string) - 1] = '\0';
            }
            LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "接收到温湿度响应帧(%d字节): %s", rx_len, hex_string);
            
            // 尝试解析温湿度传感器数据
            if (parse_temp_humid_data(rx_buffer, rx_len) == 0) {
                LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "温湿度: %.1f°C, %.1f%%", 
                          g_temp_humid_data.temperature, g_temp_humid_data.humidity);
                last_success_time = current_time;
                consecutive_failures = 0;
            } else {
                LOG_WARN(LOG_TO_FILE, RS485_MODULE, "温湿度数据解析失败");
                consecutive_failures++;
            }
        } else {
            LOG_WARN(LOG_TO_FILE, RS485_MODULE, "温湿度传感器无响应或超时");
            consecutive_failures++;
        }
        
        // 短暂延时，避免总线冲突
        nanosleep(&poll_interval, NULL);
        
        /*
        // 3. 依次查询4个拉力传感器数据（Modbus RTU格式）
        for (i = 0; i < 4; i++) {
            uint8_t device_addr = FORCE_SENSOR1_ADDR + i;
            
            // 根据7系放大器通讯协议V3.1，使用功能码03读取拉力值
            memset(tx_buffer, 0, RS485_TX_BUFFER_SIZE);
            tx_len = build_modbus_request(device_addr, MODBUS_READ_HOLDING_REGISTERS, 1, 2, tx_buffer);
            
            memset(rx_buffer, 0, RS485_RX_BUFFER_SIZE);
            rx_len = rs485_send_receive(g_rs485_fd, tx_buffer, tx_len, rx_buffer, RS485_RX_BUFFER_SIZE, RS485_RESPONSE_TIMEOUT_MS);
            
            if (rx_len > 0) {
                // 尝试解析拉力传感器数据
                if (parse_force_sensor_data(rx_buffer, rx_len, i) == 0) {
                    LOG_DEBUG(LOG_TO_CONSOLE_ONLY, RS485_MODULE, "拉力%d: %.2f N", i + 1, g_force_sensor_data[i].force);
                    last_success_time = current_time;
                    consecutive_failures = 0;
                } else {
                    consecutive_failures++;
                }
            } else {
                consecutive_failures++;
            }
            
            // 短暂延时，避免总线冲突
            nanosleep(&poll_interval, NULL);
        }
        */
        
        // 动态调整轮询间隔
        if (consecutive_failures > 5) {
            // 如果连续失败，增加延时
            poll_interval.tv_nsec = 200000000;  // 200ms
            
            // 如果连续失败次数过多，尝试重新初始化
            if (consecutive_failures > 20) {
                LOG_ERROR(LOG_TO_FILE, RS485_MODULE, "连续通信失败，尝试重新初始化");
                rs485_close(g_rs485_fd);
                usleep(500000);  // 等待500ms
                g_rs485_fd = rs485_init(RS485_DEVICE, RS485_BAUDRATE);
                consecutive_failures = 0;
            }
        } else {
            // 如果通信正常，恢复默认延时
            poll_interval.tv_nsec = 100000000;  // 100ms
        }
        
        // 一轮查询完成后，等待2秒再进行下一轮采集
        struct timespec main_loop_interval = {2, 0};  // 2秒
        nanosleep(&main_loop_interval, NULL);
    }
    
    // 关闭串口
    rs485_close(g_rs485_fd);
    g_rs485_fd = -1;
    
    LOG_INFO(LOG_TO_FILE, RS485_MODULE, "线程9退出");
    return NULL;
} 

/**
 * @brief 停止线程9
 */
void thread9_stop(void) {
    g_thread_running = 0;
    LOG_INFO(LOG_TO_FILE, RS485_MODULE, "线程9停止中");
}

/**
 * @brief 检查线程9是否正在运行
 * 
 * @return int 1-正在运行，0-已停止
 */
int thread9_is_running(void) {
    return g_thread_running;
}

/**
 * @brief 检查设备数据是否有效
 * 
 * @param timestamp 数据时间戳
 * @param valid_flag 数据有效标志
 * @param max_age_sec 最大允许的数据年龄（秒）
 * @return int 1-数据有效，0-数据无效或超时
 */
int check_data_validity(uint32_t timestamp, uint8_t valid_flag, uint32_t max_age_sec) {
    if (!valid_flag) {
        return 0;  // 数据无效
    }
    
    time_t current_time = time(NULL);
    if (current_time - timestamp > max_age_sec) {
        return 0;  // 数据超时
    }
    
    return 1;  // 数据有效
} 